<script>
import {
  defineComponent,
  ref,
  watch,
  onMounted,
  getCurrentInstance,
  computed,
} from 'vue';
import FanAspectRatio from '../aspect-ratio/aspect-ratio.vue';
import FanContactButton from '../contact-button/contact-button.vue';
import FanImage from '../image/image.vue';

import {
  createNamespace,
  createUniqueId,
  getElementBounding,
  transformStyleSize,
} from '../utils';
import { swiperProps, swiperEmits, useSwiperState } from './helper';
// import { ProviderKeys } from '../config';

export default defineComponent({
  name: createNamespace('Swiper')[0],
  options: {
    // https://uniapp.dcloud.io/matter.html#mp
    virtualHost: true,
  },
  components: {
    FanAspectRatio,
    FanContactButton,
    FanImage,
  },
  props: swiperProps,
  emits: swiperEmits,
  setup(props, context) {
    const uniqueId = createUniqueId({ prefix: 'fanSwiper' });
    const innerCurrent = ref(props.current);
    watch(
      () => props.current,
      (val) => {
        if (val !== innerCurrent.value) innerCurrent.value = val;
      },
    );
    watch(innerCurrent, (val, prevVal) => {
      if (val === prevVal) return;
      context.emit('update:current', val);
      context.emit('change', val);
      if (props.autoHeight) {
        if (itemRects[val]) currentHeight.value = itemRects[val].height;
        updateAutoHeight();
      }
    });

    const { swiperWidth, swiperAspectRatio } = useSwiperState(props);

    const _this = getCurrentInstance();
    const getSwiperWidth = async () => {
      const { type } = props;
      if (type !== 2) return;
      const rect = await getElementBounding({
        selector: '#' + uniqueId,
        scope: _this,
      });
      if (!rect || !rect.watch) return;
      swiperWidth.value = rect.width;
    };
    onMounted(getSwiperWidth);
    watch(() => props.customStyle, getSwiperWidth);

    let autoHeightTimer;
    let itemRects = [];
    const currentHeight = ref(0);
    const theStyle = computed(() => {
      const s = transformStyleSize(props.customStyle);
      if (!props.autoHeight) return s;
      return `${s}height:${currentHeight.value}px;`;
    });
    const updateAutoHeight = () => {
      if (autoHeightTimer) clearTimeout(autoHeightTimer);
      const i = innerCurrent.value;
      setTimeout(async () => {
        const rect = await getElementBounding({
          selector: '.fan-swiper__item--active',
          scope: _this,
        });
        if (rect?.height !== itemRects[i]?.height) {
          if (rect.height) itemRects[i] = rect;
          // 对于存在图片懒加载的内容
          autoHeightTimer = setTimeout(updateAutoHeight, 150);
        } else {
          currentHeight.value = rect?.height;
        }
      }, 0);
    };
    // const getItemRects = async () => {
    // 	const rects = await getElementBounding({ selector: '.fan-swiper__item', selectAll: true, scope: _this })
    // 	console.log(555, rects)
    // 	if (rects?.length) itemRects = rects
    // }
    onMounted(() => {
      if (props.autoHeight) updateAutoHeight();
    });
    // provide(ProviderKeys.swiperUpdateAutoHeight, updateAutoHeight);

    const onClick = (e, i) => {
      context.emit('click', e, i);
    };

    const showSlot = computed(() => {
      return props.customItem || context.slots.default;
    });
    const onChange = (e) => {
      const source = e.detail?.source
      if (source == 'autoplay' || source == 'touch') {
        innerCurrent.value = e.detail.current;
      }
    };

    return {
      uniqueId,
      theStyle,
      innerCurrent,
      swiperAspectRatio,
      showSlot,
      onClick,
      onChange,
    };
  },
});
</script>

<template>
  <FanAspectRatio v-if="list && list.length" :style="theStyle" :aspect-ratio="swiperAspectRatio">
    <swiper :id="uniqueId" style="height: 100%; max-height: 100%" adjust-height="none"
      :indicator-dots="list.length > 1 && indicator" indicator-color="#f6f6f6"
      :indicator-active-color="indicatorActiveColor" :autoplay="!!autoplay" :interval="autoplay" :circular="loop"
      :duration="duration" :current="innerCurrent" :vertical="vertical" :previous-margin="type === 2 ? '38px' : '0'"
      :next-margin="type === 2 ? '38px' : '0'" @change="onChange">
      <swiper-item v-for="(item, index) in list" :key="index">
        <view :style="{ height: autoHeight ? 'auto' : '100%' }" class="fan-swiper__item" :class="{
    'fan-swiper__item--type2': type === 2,
    'fan-swiper__item--active': innerCurrent === index,
  }">
          <slot v-if="showSlot" :item="item" :index="index" :active="index === innerCurrent" />
          <template v-else>
            <FanImage :show-menu-by-longpress="showMenuByLongpress" :src="item.cover"
              :mode="autoHeight ? 'widthFix' : 'aspectFill'" :aspect-ratio="autoHeight ? 0 : aspectRatio"
              :radius="innerRadius" @click="onClick(item, index)" />
          </template>

          <FanContactButton v-if="item.link && item.link.mpContact" :full="true" :mp-contact="item.link.mpContact" />
        </view>
      </swiper-item>
    </swiper>
  </FanAspectRatio>
</template>

<style lang="less">
.fan-swiper__item {
  position: relative;
  width: 100%;
  height: 100%;

  &--type2 {
    transform: scale(0.88);
    transition: transform 0.3s;
    box-sizing: border-box;

    &.fan-swiper__item--active {
      transform: none;
    }
  }
}
</style>
